package com.ehotting.edsta.circuitDesign.gen;


import com.ehotting.eaf.redis.service.RedisService;
import com.ehotting.edsta.circuitDesign.bean.CircuitPropertyBean;
import com.ehotting.edsta.circuitDesign.bean.Constant;
import com.ehotting.edsta.circuitDesign.enums.SignalTypeEnum;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Component
public class PropertyTipPackageHelper {

    @Autowired
    private RedisService redisService;

    @Data
    public static class TipCollectionIds{
        private Map<String,Set<Long>> sensorIds = new HashMap<>();
        private Set<Long> controllerIds = new HashSet<>();
        private Set<Long> powerIds = new HashSet<>();
    }
    @Data
    class FilterTipsBack{
        // 质量等级
        private Set<String> qualitygradeList = new HashSet<>();

        // 采集类型
        private Set<String> signalTypeList = new HashSet<>();
        // 最小频率-信号带宽
        private Float oneFMin = null;
        // 最大频率-信号带宽
        private Float fMaxFloat = null;
        // 最小输入范围
        private Float oneInputMinRange = null;
        // 最大输入范围
        private Float inputMaxRangeFloat = null;
        // 采样率
        private Float sampleMaxFloat = null;
        // 采样分辨率
        private Set<String> adcSamplingBitList = new HashSet<>();

        // 数字电路类型
        private Set<String> inTypeList = new HashSet<>();
        // 输入信号电压
        private List<Float> inputVoltageRangeList = new ArrayList<>();

        // 总线通信类型
        private Set<String> cpuInterfaceList = new HashSet<>();
        // 处理器类型
        private Set<String> controllerList = new HashSet<>();
        // 电压等级
        private Set<String> inVoltageList = new HashSet<>();
        // 最大功率
        private List<Float> maxPowerList = new ArrayList<>();

        // 电路id集合
        private Set<Long> circuitIdList = new HashSet<>();
        private TipCollectionIds tipCollectionIds = new TipCollectionIds();
    }

    /**
     * 打包属性可选值------------------------------------------------------------------------------------------------------
     */
    public LinkedHashMap packageProperty(CircuitPropertyBean circuitPropertyBean,String mainProjectId, String page){
        LinkedHashMap<String, Object> objectMap = new LinkedHashMap<>();

        FilterTipsBack filterTipsBack = new FilterTipsBack();
        TipCollectionIds redTipCollectionIds = redisService.getCacheObject(Constant.CIRCUIT_TIP_IDS + mainProjectId);
        if(redTipCollectionIds != null){
            filterTipsBack.setTipCollectionIds(redTipCollectionIds);
        }


        switch ((int) Float.parseFloat(page)){
            case 1:
                // 打包数据处理电路与电源电路
                objectMap = packageControllerAndPower(filterTipsBack,circuitPropertyBean);
                break;
            case 2:
                // 打包数据采集电路（模拟）
                objectMap = packageAnalog(filterTipsBack,circuitPropertyBean,page);
                break;
            case 3:
                // 打包数据采集电路（数字）
                objectMap = packageDigital(filterTipsBack,circuitPropertyBean,page);
                break;
            default:
                System.out.println("\n\npage is error:"+page+"\n\n");
                break;
        }


        // 上传电路id到缓存
        objectMap.put("mainProjectId", mainProjectId);

        filterTipsBack.getTipCollectionIds().getSensorIds().remove("2.0");
        filterTipsBack.getTipCollectionIds().getSensorIds().remove("3.0");
        redisService.setCacheObject(Constant.CIRCUIT_TIP_IDS + mainProjectId, filterTipsBack.getTipCollectionIds(), Constant.EXPIRE_TIME, TimeUnit.SECONDS);

        return objectMap;
    }

    private static LinkedHashMap<String, Object> packageDigital(FilterTipsBack filterTipsBack,CircuitPropertyBean circuitPropertyBean,String page){
        LinkedHashMap<String, Object> objectMap = new LinkedHashMap<>();

        filterTipsBack.getTipCollectionIds().getSensorIds().put(page,new HashSet<Long>());

        // 输入信号电压
        Float inputVoltageRangeMin = null;
        Float inputVoltageRangeMax = null;
        for (CircuitPropertyBean.CircuitBean circuitBean : circuitPropertyBean.getSensorCircuitListBean()){
            if (circuitBean.getPropertyMap() == null){
                continue;
            }

            // 模拟电路和数字电路要分开处理
            if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.SIGNALTYPE.getCode()).getValue()
                    .equals(String.valueOf(SignalTypeEnum.OTHER.getValue()))){
                /**
                 * 数字电路
                 */
                // 数字信号输入类型
                if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.INTYPE.getCode()) != null){
                    filterTipsBack.getInTypeList().add(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.INTYPE.getCode()).getValue());
                }

                // 输入信号电压
                String inputVoltageRange = circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.INPUTVOLTAGERANGE.getCode()).getValue();
                inputVoltageRangeMin = findVoltageMin(inputVoltageRangeMin, inputVoltageRange);
                inputVoltageRangeMax = findVoltageMax(inputVoltageRangeMax, inputVoltageRange);

            }

//            filterTipsBack.getCircuitIdList().add(circuitBean.getId());
            filterTipsBack.getTipCollectionIds().getSensorIds().get(page).add(circuitBean.getId());
        }
        // 输入信号电压
        filterTipsBack.getInputVoltageRangeList().add(inputVoltageRangeMin);
        filterTipsBack.getInputVoltageRangeList().add(inputVoltageRangeMax);

        // -----------------组装返回前端的数据-------------------
        objectMap.put("intype", filterTipsBack.getInTypeList());
        objectMap.put("involt", filterTipsBack.getInputVoltageRangeList());

        return objectMap;
    }

    private static LinkedHashMap<String, Object> packageAnalog(FilterTipsBack filterTipsBack,CircuitPropertyBean circuitPropertyBean,String page){
        LinkedHashMap<String, Object> objectMap = new LinkedHashMap<>();

        filterTipsBack.getTipCollectionIds().getSensorIds().put(page,new HashSet<Long>());


        for (CircuitPropertyBean.CircuitBean circuitBean : circuitPropertyBean.getSensorCircuitListBean()){
            if (circuitBean.getPropertyMap() == null){
                continue;
            }

            if (!circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.SIGNALTYPE.getCode()).getValue()
                    .equals(String.valueOf(SignalTypeEnum.OTHER.getValue()))){
                /**
                 * 模拟电路
                 */
                // 采集类型
                if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.SIGNALTYPE.getCode()) != null){
                    filterTipsBack.getSignalTypeList().add(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.SIGNALTYPE.getCode()).getValue());
                }

                // 采样分辨率（可以为空，要做判空处理）
                if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.ADCSAMPLINGBIT.getCode()) != null){
                    int value = (int) Float.parseFloat(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.ADCSAMPLINGBIT.getCode()).getValue());
                    filterTipsBack.getAdcSamplingBitList().add(String.valueOf(value));
                }

                // 最小频率-信号带宽（特殊处理）
                if(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.FMIN.getCode()) != null){
                    float fMin = Float.parseFloat(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.FMIN.getCode()).getValue());
                    filterTipsBack.setOneFMin(findMin(filterTipsBack.getOneFMin(), fMin));
                }

                // 最大频率-信号带宽（特殊处理）
                if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.FMAX.getCode()) != null) {
                    float fMax = Float.parseFloat(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.FMAX.getCode()).getValue());
                    filterTipsBack.setFMaxFloat(findMax(filterTipsBack.getFMaxFloat(), fMax));
                }

                // 最小输入范围（特殊处理）
                if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.INPUTMINRANGE.getCode()) != null){
                    float inputMinRange = Float.parseFloat(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.INPUTMINRANGE.getCode()).getValue());
                    filterTipsBack.setOneInputMinRange(findMin(filterTipsBack.getOneInputMinRange(), inputMinRange));
                }

                // 最大输入范围（特殊处理）
                if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.INPUTMAXRANGE.getCode()) != null) {
                    float inputMaxRange = Float.parseFloat(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.INPUTMAXRANGE.getCode()).getValue());
                    filterTipsBack.setInputMaxRangeFloat(findMax(filterTipsBack.getInputMaxRangeFloat(), inputMaxRange));
                }

                // 采样率（可以为空，要做判空处理）
                if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.SAMPLE.getCode()) != null){
                    float sampleMax = Float.parseFloat(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.SAMPLE.getCode()).getValue());
                    filterTipsBack.setSampleMaxFloat(findMax(filterTipsBack.getSampleMaxFloat(), sampleMax));
                }

            }

//            filterTipsBack.getCircuitIdList().add(circuitBean.getId());

            filterTipsBack.getTipCollectionIds().getSensorIds().get(page).add(circuitBean.getId());
        }

        // samplingbit向下兼容
        samplingBitBackwardsCompatible(filterTipsBack.getAdcSamplingBitList());
        // -----------------组装返回前端的数据-------------------
        objectMap.put("analoguetype", filterTipsBack.getSignalTypeList());
        objectMap.put("signalmin", filterTipsBack.getOneFMin());
        objectMap.put("signalmax", filterTipsBack.getFMaxFloat());
        objectMap.put("mindatarange", filterTipsBack.getOneInputMinRange());
        objectMap.put("maxdatarange", filterTipsBack.getInputMaxRangeFloat());
        objectMap.put("sample", filterTipsBack.getSampleMaxFloat());
        objectMap.put("samplingbit", filterTipsBack.getAdcSamplingBitList());

        return objectMap;
    }

    private static void samplingBitBackwardsCompatible(Set<String> samplingBitList){
        double samplingBitMax = 0.0;
        for(String s : samplingBitList){
            samplingBitMax = Double.parseDouble(s) > samplingBitMax ? Double.parseDouble(s) : samplingBitMax;
        }
        if(samplingBitMax>=24){
            samplingBitList.addAll(Arrays.asList("24","16","12","8"));
            return;
        }
        if(samplingBitMax>=16){
            samplingBitList.addAll(Arrays.asList("16","12","8"));
            return;
        }
        if(samplingBitMax>=12){
            samplingBitList.addAll(Arrays.asList("12","8"));
            return;
        }
        if(samplingBitMax>=8){
            samplingBitList.add("8");

        }
    }

    private static LinkedHashMap<String, Object> packageControllerAndPower(FilterTipsBack filterTipsBack,CircuitPropertyBean circuitPropertyBean){
        filterTipsBack.getTipCollectionIds().setControllerIds(new HashSet<>());
        filterTipsBack.getTipCollectionIds().setPowerIds(new HashSet<>());
        LinkedHashMap<String, Object> objectMap = new LinkedHashMap<>();
        // 最大功率
        Float maxPowerMax = null;
        // 最小功率
        Float minPowerMin = null;

        // 组装数据处理电路属性
        for (CircuitPropertyBean.CircuitBean circuitBean : circuitPropertyBean.getControllerCircuitList()){
            if (circuitBean.getPropertyMap() == null){
                continue;
            }

            // 质量等级
            if(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.QUALITYGRADE.getCode()) != null){
                filterTipsBack.getQualitygradeList().add(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.QUALITYGRADE.getCode()).getValue());
            }

            // 总线通信类型
            if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.CPUINTERFACE.getCode()) != null){
                String cpuInterfaceValue = circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.CPUINTERFACE.getCode()).getValue();
                if (!cpuInterfaceValue.equals("CAN")){
                    filterTipsBack.getCpuInterfaceList().add(cpuInterfaceValue+"-M");
                    filterTipsBack.getCpuInterfaceList().add(cpuInterfaceValue+"-S");
                }else {
                    filterTipsBack.getCpuInterfaceList().add(cpuInterfaceValue);
                }
            }

            // 处理器类型
            if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.CONTROLLER.getCode()) != null){
                filterTipsBack.getControllerList().add(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.CONTROLLER.getCode()).getValue());
            }

//            filterTipsBack.getCircuitIdList().add(circuitBean.getId());
            filterTipsBack.getTipCollectionIds().getControllerIds().add(circuitBean.getId());
        }

        // 组装电源电路属性
        HashSet<String> hashSet = new HashSet<>();
        for (CircuitPropertyBean.CircuitBean circuitBean : circuitPropertyBean.getPowerCircuitList()) {
            if (circuitBean.getPropertyMap() == null){
                continue;
            }
            if(hashSet.contains(circuitBean.getPropertyMap().get("outVoltage").toString())){
                continue;
            }
            // 质量等级
            if(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.QUALITYGRADE.getCode()) != null){
                filterTipsBack.getQualitygradeList().add(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.QUALITYGRADE.getCode()).getValue());
            }

            // 电压等级
            if(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.INVOLTAGE.getCode()) != null){
                String[] inVoltageArr = circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.INVOLTAGE.getCode()).getValue().split(",");
                filterTipsBack.getInVoltageList().addAll(Arrays.asList(inVoltageArr));
            }

            // 最大功率
            if (circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.MAXPOWER.getCode()) != null){
                float maxPower = Float.parseFloat(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.MAXPOWER.getCode()).getValue());
                maxPowerMax = findMax(maxPowerMax, maxPower);
                minPowerMin = findMin(minPowerMin, maxPower);
            }

            hashSet.add(circuitBean.getPropertyMap().get("outVoltage").toString());
            filterTipsBack.getTipCollectionIds().getPowerIds().add(circuitBean.getId());

        }

        // 组装数据采集电路属性
        for (CircuitPropertyBean.CircuitBean circuitBean : circuitPropertyBean.getSensorCircuitListBean()) {
            if (circuitBean.getPropertyMap() == null) {
                continue;
            }

            // 质量等级
            if(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.QUALITYGRADE.getCode()) != null){
                filterTipsBack.getQualitygradeList().add(circuitBean.getPropertyMap().get(CircuitPropertyBean.PropertyEnum.QUALITYGRADE.getCode()).getValue());
            }

        }

        // 最大功率
        filterTipsBack.getMaxPowerList().add(minPowerMin);
        filterTipsBack.getMaxPowerList().add(maxPowerMax);

        // 处理电源的数量


        // -----------------组装返回前端的数据-------------------
        objectMap.put("qualitygrade", filterTipsBack.getQualitygradeList());
        objectMap.put("bus", filterTipsBack.getCpuInterfaceList());
        objectMap.put("controller", filterTipsBack.getControllerList());
        objectMap.put("volt", filterTipsBack.getInVoltageList());
        objectMap.put("power", filterTipsBack.getMaxPowerList().get(0));

        return objectMap;
    }


    /**
     * 打包属性小工具---------------------------------------------------------------------------------
     */
    private static float findMin(Float inputMin, float minValue){
        if (inputMin == null || minValue < inputMin){
            return minValue;
        }
        return inputMin;
    }

    private static float findMax(Float inputMax, float maxValue){
        if (inputMax == null || maxValue > inputMax){
            return maxValue;
        }
        return inputMax;
    }

    private static Float findVoltageMin(Float inputMin, String value) {
        float minValue = 0;
        if (value.contains("-")){
            minValue = Float.parseFloat(value.split("-")[0]);
        }

        if (inputMin == null || minValue < inputMin){
            return minValue;
        }

        return inputMin;

    }

    private static Float findVoltageMax(Float inputMax, String value) {
        float maxValue;
        if (value.contains("-")){
            maxValue = Float.parseFloat(value.split("-")[1]);
        }else {
            maxValue = Float.parseFloat(value);
        }

        if (inputMax == null || maxValue > inputMax){
            return maxValue;
        }

        return inputMax;

    }

    private static String propNull(String propValue){

        return propValue;
    }
}
